--agent for ability lvm and item lvm
require "utils"

local MINIMUM_COLLISION_DAMAGE = 10
local MAXIMUM_COLLISION_DAMAGE = 1000
local radius = 200
local speed_normal = 1500
local speed_channel = 2500
local speed_utra = 2500

-- local colorSet = {
-- 	Vector(0.255,0.255,0.255),
-- 	Vector(0.224,0.128,0.049),
-- 	Vector(0.025,0.148,0.117),
-- 	Vector(0.004,0.077,0.034),
-- 	Vector(0.240,0.027,0.045)
-- }
local colorSet = {
	Vector(201,190,183),
	Vector(252,246,151),
	Vector(255,224,17),
	Vector(41,221,36),
	Vector(0,162,255),
	Vector(255,123,43),
	Vector(255,44,44),
	Vector(240,27,45),
	Vector(185,65,0)
}

local pHitShield = "particles/econ/items/monkey_king/arcana/fire/mk_arcana_fire_spring_channel_rings.vpcf"
local pDestroyShield = "particles/units/heroes/hero_oracle/oracle_false_promise_cast_enemy.vpcf"
local pHitUnit = "particles/econ/items/crystal_maiden/crystal_maiden_maiden_of_icewrack/cm_arcana_pup_flee.vpcf"
function DamageChange(collider)
	local entindex = collider.ability
	local ability = EntIndexToHScript(entindex)
	local damage1 = ability:GetSpecialValueFor("damage") or 0
	collider._extra_damage = collider._extra_damage + damage1 * collider.ts_time
end

function CreateSpeedBall(caster,mass,fric)
	local locationVector = caster:GetAbsOrigin()
	mass = mass or 15
	fric = fric or 0.02
	local speedball = CreateUnitByName("speedball", locationVector, true, nil, nil, DOTA_TEAM_NOTEAM)
	Physics:Unit(speedball)
  	speedball:SetMass(mass)
  	speedball:AdaptiveNavGridLookahead(true)
  	speedball:SetNavCollisionType(PHYSICS_NAV_BOUNCE)
  	speedball:SetPhysicsFriction(fric)
  	speedball:SetOwner(caster)
  	speedball:SetTeam(caster:GetTeamNumber())
  	speedball:SetPhysicsVelocityMax(4500)
    speedball:FollowNavMesh(true)
  	speedball:SetGroundBehavior(PHYSICS_GROUND_LOCK)
  	speedball.max_pz = 5
  	local scale = speedball:GetModelScale()
  	local r_roll = scale * (speedball:GetModelRadius() - 80)
    speedball:OnPhysicsFrame(function (unit)
    	if not IsValidEntity(unit) then
    		return
    	end
    	-- Rotate the ball
		local vAngles = unit:GetPhysicsVelocity() * 360 / (2 * 3.1415926 * r_roll * 30)
		vAngles = QAngle(vAngles.x, 0, -1 * vAngles.y)
		
		local angles = RotateOrientation(vAngles, unit:GetAngles())
		unit:SetAngles(angles.x, angles.y, angles.z)

    	local speed = unit:GetPhysicsVelocity():Length2D()
    	if speed < 200 and speed > 0 and not unit.alive then
	       	unit:SetPhysicsVelocity(Vector(0, 0, 0))
   			unit:OnPhysicsFrame(nil)
   			removeSpeedBall(unit)
    	end
    end)
    speedball._owner = caster:GetEntityIndex()
    speedball:OnBounce(function(unit, normal)
      	EmitSoundOn("DOTA_Item.Mjollnir.DeActivate",unit)
		TanShe(unit)
    end)
    speedball._extra_damage = 0
    changeBulletLife(speedball,1)
    SetupSpeedBallCollider(speedball)
  	return speedball
end

--todo add伤害公式待做
function calcDamage()

end


function ApplyImpactDamage( collider, collided)
	checkShangShield(collided,collider)
	checkAntiPhysicShield(collided,collider)
	local modifierList = {
		"modifier_huzhao1",
		"modifier_huzhao2",
		"modifier_huzhao3",
		"modifier_shanghudun"
	}
	for i=1,#modifierList do
		local modifierName = modifierList[i]
		local hModifier = collided:FindModifierByName(modifierName)
		if hModifier then
			local count = hModifier:GetStackCount()
			if count == 1 then  --这里不用<=1  可以方便另外一种没有次数限制的防护罩的判定
				
				collided:RemoveModifierByName(modifierName)
			else

				hModifier:SetStackCount(count-1)
				local p = ParticleManager:CreateParticle(pHitShield,PATTACH_ABSORIGIN_FOLLOW , collided)
				ParticleManager:SetParticleControl(p,0,collided:GetAbsOrigin())
				--todo 播放护罩被打中的特效
			end
			
			return
		end
	end

	local hitID = ParticleManager:CreateParticle(pHitUnit,PATTACH_ABSORIGIN_FOLLOW, collided)
	ParticleManager:SetParticleControl(hitID,0,collided:GetAbsOrigin())
	--伤害计算公式
	--[[
		tscs:弹射次数
		sp:当前速度
		ext:额外伤害

	]]

	local colliderSpeed = collider:GetPhysicsVelocity():Length2D()
	local extra_damage = collider._extra_damage or 0

	if extra_damage < 0 then return end
	local killer = EntIndexToHScript(collider._owner)
	local damageTable = {
		victim = collided,
		attacker = killer,
		damage = extra_damage,
		damage_type = DAMAGE_TYPE_PURE,
	}
	local result = ApplyDamage(damageTable)
	if killer ~= collided then
		updateRank(result,killer,collided)
	end
end

function removeSpeedBall(ball)
	local partID = ball.partID
   	if partID then
		ParticleManager:DestroyParticle(partID, true)
	end
	local entIndex = ball:GetEntityIndex()
	if ball.RemoveCollider then
		ball:RemoveCollider()
	end
	--这里用Util_Remove貌似有几率闪退
	--ball:ForceKill(false)
	ball:RemoveSelf()
	GameRules.PHYSIC_UNIT[entIndex] = nil
end

function changeParticleColor(ball)
	 -- local partID = ball.partID
	local pz_time = ball.pz_time
	-- ParticleManager:SetParticleControl(partID,12,colorSet[pz_time])
	ball:SetRenderColor(colorSet[pz_time].x,colorSet[pz_time].y,colorSet[pz_time].z)
end

function useBall(caster,ability)
	local hModifier = caster:FindModifierByName("modifier_chongneng")
	local count = hModifier:GetStackCount()
	if count <= 0 then
		ability:EndCooldown()
		--todo add 添加子弹不够的提示语
		showWarn("TIP_NOT_ENOUGHT_BULLET",caster)
		return false
	end
	hModifier:SetStackCount(count-1)
	return true
end

--如果发现莫名的BUG，有可能是因为有个别报错被pcall捕获了只要有一个报错 有可能导致整个physic没法使用
--ability in slot 1
function ball1(data)
	local caster = data.caster
	local ability = data.ability
	if not useBall(caster,ability) then
		return
	end
	local targetPos = data.target_points[1]
	local ball = CreateSpeedBall(caster)
	ball.ability = ability:GetEntityIndex()
	if data.particle then
		local particleID = ParticleManager:CreateParticle(data.particle, PATTACH_ABSORIGIN_FOLLOW, ball)
		ParticleManager:SetParticleControl(particleID, 13, ball:GetAbsOrigin())
		ball.partID = particleID
		ball:SetOriginalModel("models/development/invisiblebox.vmdl")
	end
	
	local dir = (targetPos - caster:GetAbsOrigin() ):Normalized()
	ball.ts_time = 1
	ball:AddPhysicsVelocity(dir * speed_normal)
end


--ability in slot 2
function ball2(data)
	local caster = data.caster
	local ability = data.ability
	if not useBall(caster,ability) then
		return
	end
	if not ability.ts_time then
		ability.ts_time = 0
	end
	local targetPos = data.target_points[1]
	local ball = CreateSpeedBall(caster)
	ball.ability = ability:GetEntityIndex()
	if data.particle then
		local particleID = ParticleManager:CreateParticle(data.particle, PATTACH_ABSORIGIN_FOLLOW, ball)
		ParticleManager:SetParticleControl(particleID, 13, ball:GetAbsOrigin())
		ball.partID = particleID
		ball:SetOriginalModel("models/development/invisiblebox.vmdl")
	end
	local dir = (targetPos - caster:GetAbsOrigin() ):Normalized()
	ball.ts_time = ability.ts_time
	ball:AddPhysicsVelocity(dir * speed_channel)
end

--ability in slot 3
function ball3(data)
	local caster = data.caster
	local add = data.add
	local hModifier = caster:FindModifierByName("modifier_chongneng")
	local curCount = hModifier:GetStackCount()
	curCount = math.min(curCount+add,15)
	hModifier:SetStackCount(curCount)
end

--ability in slot 4
function ball4(data)
	local caster = data.caster
	local ability = data.ability
	if not useBall(caster,ability) then
		return
	end
	if not ability.ts_time then
		ability.ts_time = 0
	end
	local targetPos = data.target_points[1]
	local ball = CreateSpeedBall(caster,200,0.1)
	ball.ability = ability:GetEntityIndex()
	local particleID = ParticleManager:CreateParticle(data.particle, PATTACH_ABSORIGIN_FOLLOW, ball)
    ball.partID = particleID
    ParticleManager:SetParticleControl(particleID, 13, ball:GetAbsOrigin())
	local dir = (targetPos - caster:GetAbsOrigin() ):Normalized()
	ball.ts_time = ability.ts_time
	ball:AddPhysicsVelocity(dir * speed_utra)
end

function SetupSpeedBallCollider(speedball)
	speedball.hitself = true
	local colliderName = DoUniqueString("speedball")
	local ball_collider = speedball:AddColliderFromProfile("momentum")
    ball_collider.radius = 200
  	ball_collider.name = colliderName
	ball_collider.block = true
	--ball_collider.draw = {color = Vector(200,50,50), alpha = 5, radius = 100}
	ball_collider.filter = GameRules.PHYSIC_UNIT
	GameRules.PHYSIC_UNIT[speedball:GetEntityIndex()] = speedball
	ball_collider.test = function (self, collider, collided)
		--需要避免子弹出手时与英雄的碰撞,避免的思路是当投射物至少经过一次弹射之后才能打到施法者本身
		if collider.hitself and collider._owner == collided:GetEntityIndex() then
			return false
		end
		return true
	end
  -- this handles when two balls collide with eachother
	ball_collider.preaction = function(self, collider, collided)	
		if IsPhysicsUnit(collided) and collided.GetUnitName ~= nil and collided:GetUnitName() == "speedball" then
			-- game sound
			EmitGlobalSound("n_creep_HarpyStorm.ChainLighting")

			local collidedSpeed = collided:GetPhysicsVelocity():Length2D()
			local colliderSpeed = collider:GetPhysicsVelocity():Length2D()

			-- add a particle to the reflected ball, and track it for deletion
			local entIndex = collided:GetEntityIndex()
			if not collided.partID then
			--if GameRules.SPEEDBALL_PARTICLES[entIndex] == nil then
			-- local colliderTeamColor = collider:GetTeamNumber()
			-- if colliderTeamColor == 2 then
			--   colliderTeamColor = "teal"
			-- elseif colliderTeamColor == 3 then
			--   colliderTeamColor = "yellow"
			-- elseif colliderTeamColor == 6 then
			--   colliderTeamColor = "pink"
			-- else -- teamColor == 7
			--   colliderTeamColor = "orange"
			-- end

			-- local collidedTeamColor = collided:GetTeamNumber()
			-- if collidedTeamColor == 2 then
			--   collidedTeamColor = "teal"
			-- elseif collidedTeamColor == 3 then
			--   collidedTeamColor = "yellow"
			-- elseif collidedTeamColor == 6 then
			--   collidedTeamColor = "pink"
			-- else -- teamColor == 7
			--   collidedTeamColor = "orange"
			-- end

			-- if collidedSpeed < colliderSpeed then
			--   local particleID = ParticleManager:CreateParticle("particles/ball_trail/".. colliderTeamColor .."/spirit_breaker_charge_iron.vpcf", PATTACH_ABSORIGIN_FOLLOW, collided)
			--   ParticleManager:SetParticleControl(particleID, 0, collided:GetAbsOrigin())
			--   GameRules.SPEEDBALL_PARTICLES[entIndex] = particleID
			-- elseif collidedSpeed > colliderSpeed then
			--   local particleID = ParticleManager:CreateParticle("particles/ball_trail/".. collidedTeamColor .."/spirit_breaker_charge_iron.vpcf", PATTACH_ABSORIGIN_FOLLOW, collided)
			--   ParticleManager:SetParticleControl(particleID, 0, collider:GetAbsOrigin())
			--   GameRules.SPEEDBALL_PARTICLES[entIndex] = particleID
			-- end

			-- collided:OnPhysicsFrame(function(unit) 
			--   local speed = unit:GetPhysicsVelocity():Length2D()
			--   if speed < 200 and speed > 0 then
			--     unit:SetPhysicsVelocity(Vector(0, 0, 0))
			--     unit:OnPhysicsFrame(nil)
			--     removeSpeedBall(unit)
			--   end
			-- end)
	      	else 
	        -- 
	      	end

	      	--[[
	      	环形警告特效
			self.nPreviewFX = ParticleManager:CreateParticle( "particles/darkmoon_creep_warning.vpcf", PATTACH_ABSORIGIN_FOLLOW, self:GetCaster() )
		ParticleManager:SetParticleControlEnt( self.nPreviewFX, 0, self:GetCaster(), PATTACH_ABSORIGIN_FOLLOW, nil, self:GetCaster():GetOrigin(), true )
		ParticleManager:SetParticleControl( self.nPreviewFX, 1, Vector( 325, 325, 325 ) )
		ParticleManager:SetParticleControl( self.nPreviewFX, 15, Vector( 255, 140, 0 ) )
	      	]]
			if collided._owner and collider._owner then
	  			if collidedSpeed < colliderSpeed then

					--DebugPrint('[Ownership Transfered] Collider transfers to collided')
					collided:SetOwner(collider:GetOwner())
				--	collided:SetTeam(collider:GetTeam())
					collided._owner = collider._owner or collider:GetEntityIndex()
				elseif collidedSpeed > colliderSpeed then

					--DebugPrint('[Ownership Transfered] Collided trasnfers to collider')
					 collider:SetOwner(collided:GetOwner())
				--	 collider:SetTeam(collided:GetTeam())
					collider._owner = collided._owner or entIndex
				end
			end
		end
      -- if balls are not on the same team apply ownership to the slower moving ball from the faster.
	  	
	end
	-- postaction is what occurs when the collider detects a pass on its 'test' function. Here we apply damage to the hero a ball collides with.
	ball_collider.postaction = function (self, collider, collided)
		local colliderSpeed = collider:GetPhysicsVelocity():Length2D()
		if colliderSpeed > 200 then
			TanShe(collider,collided)
			EmitSoundOn("Item.Maelstrom.Chain_Lightning", collided)
		end
	end
end
--这个函数最好放到最后，因为有remove操作
function TanShe(collider,collided)
	if collider.pz_time >= 5 then
		removeSpeedBall(collider)
		return
	end
	collider.hitself = nil
	--弹射一次伤害递增一次
	DamageChange(collider)
	if collided and collided:GetUnitName()~="speedball" then
		if collider.hitModifier then
			local ability = EntIndexToHScript(collider.ability)
			local duration = ability:GetSpecialValueFor("duration") or 1
			collided:AddNewModifier(collider,nil,collider.hitModifier, {duration=duration})
		end
		ApplyImpactDamage(collider,collided)
	end
	if IsValidEntity(collider) then
		changeBulletLife(collider,collider.pz_time + 1)
	end
end

function ball2interval(data)
	local ability = data.ability
	if not ability.ts_time then
		ability.ts_time = 0
	end
	ability.ts_time = ability.ts_time + data.interval
end

function setStackCount(data)
	local caster = data.target
	local modifierName = data.modifierName
	local hModifier = caster:FindModifierByName(modifierName)
	if hModifier then
		hModifier:SetStackCount(data.count or 1)
	end
end

function ForceStaff (keys)

	local caster = keys.caster
	local ability = keys.ability

	caster:Stop()

	ability.forced_direction = caster:GetForwardVector()
	ability.forced_distance = ability:GetSpecialValueFor("distance")
	ability.forced_speed = 50	-- * 1/30 gives a duration of ~0.4 second push time (which is what the gamepedia-site says it should be)
	ability.forced_traveled = 0

end

function ForceHorizontal( keys )

	local caster = keys.caster
	local ability = keys.ability

	if ability.forced_traveled < ability.forced_distance then
		caster:SetAbsOrigin(caster:GetAbsOrigin() + ability.forced_direction * ability.forced_speed)
		ability.forced_traveled = ability.forced_traveled + (ability.forced_direction * ability.forced_speed):Length2D()
	else
		caster:InterruptMotionControllers(true)
	end

end

function DestroyShield(data)
	local caster = data.target
	--todo  播放护罩被毁灭的特效
	EmitSoundOn("Hero_Oracle.FalsePromise.Damaged",caster)
	local p = ParticleManager:CreateParticle(pDestroyShield,PATTACH_ABSORIGIN_FOLLOW , caster)
	ParticleManager:SetParticleControl(p,0,caster:GetAbsOrigin())
end

function generateDir(target,number)
	local foward = target:GetForwardVector()
	number = number or 3
	local x = foward.x
	local y = foward.y
	local z = foward.z
	local ret = {}
	for i=1,number do
		local x_new = x*math.cos(math.pi*2/number*i)-y*math.sin(math.pi*2/number*i)
		local y_new = x*math.sin(math.pi*2/number*i)+y*math.cos(math.pi*2/number*i)
		local vec = Vector(x_new,y_new,z)
		table.insert(ret,vec)
	end
	return ret
end

--BOSS技能开始
function boss2a1(data)
	local caster = data.caster
	local ability = data.ability
	local dirlist = generateDir(caster,3)
	local pos = caster:GetAbsOrigin()
	for k,v in pairs(dirlist) do
		local ball = CreateSpeedBall(caster)
		ball.ability = ability:GetEntityIndex()
		ball:SetAbsOrigin(pos + v * 200)
		local particleID = ParticleManager:CreateParticle(data.particle, PATTACH_ABSORIGIN_FOLLOW, ball)
	    ball.partID = particleID
	    ParticleManager:SetParticleControl(particleID, 4, ball:GetAbsOrigin())
		ball.ts_time = 1
		ball:AddPhysicsVelocity(v * speed_utra)
	end
	
end

function AddAbilityPoint( data )
	local caster = data.caster
	if caster:IsRealHero() then
		caster:SetAbilityPoints(caster:GetAbilityPoints()+1)
	end
end

function boss3a3(data)
	local caster = data.caster
	local ability = data.ability
	local dirlist = generateDir(caster,6)
	local pos = caster:GetAbsOrigin()
	for k,v in pairs(dirlist) do
		local ball = CreateSpeedBall(caster)
		ball:SetAbsOrigin(pos + v * 200)
		ball.ability = ability:GetEntityIndex()
		local particleID = ParticleManager:CreateParticle(data.particle, PATTACH_ABSORIGIN_FOLLOW, ball)
	    ball.partID = particleID
	    --ParticleManager:SetParticleControl(particleID, 13, ball:GetAbsOrigin())
		ball.ts_time = 1
		ball:AddPhysicsVelocity(v * speed_utra)
	end
end

function boss1a3( data )
	local caster = data.caster
	local ability = data.ability
	local dirlist = generateDir(caster,4)
	local pos = caster:GetAbsOrigin()
	removeWarnParticle(data)
	for k,v in pairs(dirlist) do
		local ball = CreateSpeedBall(caster)
		ball:SetAbsOrigin(pos + v * 200)
		ball.ability = ability:GetEntityIndex()
		local particleID = ParticleManager:CreateParticle(data.particle, PATTACH_ABSORIGIN_FOLLOW, ball)
	    ball.partID = particleID
	    ParticleManager:SetParticleControl(particleID, 0, ball:GetAbsOrigin())
		ball.ts_time = 1
		ball:AddPhysicsVelocity(v * speed_utra)
	end
end

--[[
	缠绕子弹，没有伤害，时间较长，因为可以使用技能和道具
]]
function specialBullet( data )
	local caster = data.caster
	local ability = data.ability
	local dirlist = generateDir(caster,data.num or 3)
	local pos = caster:GetAbsOrigin()
	removeWarnParticle(data)
	for k,v in pairs(dirlist) do
		local ball = CreateSpeedBall(caster)
		ball:SetAbsOrigin(pos + v * 200)
		ball.ability = ability:GetEntityIndex()
		
		ball.ts_time = 1
		ball:AddPhysicsVelocity(v * speed_utra)
		ball.hitModifier = data.modifierName
		if data.particle then
			local particleID = ParticleManager:CreateParticle(data.particle, PATTACH_ABSORIGIN_FOLLOW, ball)
		    ball.partID = particleID
		    ParticleManager:SetParticleControl(particleID, 4, ball:GetAbsOrigin())
			ball:SetOriginalModel("models/development/invisiblebox.vmdl")
			ball:SetModel("models/development/invisiblebox.vmdl")
		end
	end
end

--[[
	眩晕子弹，没有伤害，时间较短
]]
--直接调用上面那个，传不同的modifier就行了
--[[
	反物理护盾 击中的子弹都会转化为护盾所有者所有，而且速度提升1倍
	反弹次数增加三次
	直接applymodifier即可
]]
function checkAntiPhysicShield(collided,collider)
	if collided:HasModifier("modifier_antiphysic") then
		collider:SetOwner(collided:GetOwner())
		collider.max_pz = collider.max_pz + 3
		--collider:SetTeam(collided:GetTeam())
		collider._owner = collided._owner or collided:GetEntityIndex()
		local dir = collider:GetPhysicsVelocity():Normalized()
		collider:SetPhysicsVelocity(collider:GetPhysicsVelocity()*2)
	end
end
--[[
	直接applymodifier即可
	熵变护盾  每颗子弹可以恢复对应的血量
]]
function checkShangShield(collided,collider)
	if collided:HasModifier("modifier_shanghudun") then
		local ability = EntIndexToHScript(collider.ability)
		collided:Heal(collider._extra_damage or 0,ability)
	end
end

function changeBulletLife(bullet,life)
	bullet.pz_time = life
	changeParticleColor(bullet)
end

--[[
	时光魔法   停止周围所有的子弹，1秒后从原来的方向发射出去,子弹经过时光的摧残，无法进行弹射
]]
function stopAllBullet(data)
	local caster = data.caster
	local ability = data.ability
	local bullets = FindUnitsInRadius(caster:GetTeamNumber(), caster:GetAbsOrigin(), nil,data.radius or 350,DOTA_UNIT_TARGET_TEAM_BOTH, DOTA_UNIT_TARGET_ALL,DOTA_UNIT_TARGET_FLAG_NONE, FIND_ANY_ORDER, false)
	local ids = {}
	for k,bullet in pairs(bullets) do
		if bullet.pz_time then
			bullet.alive = true
			bullet._lastSp = bullet:GetPhysicsVelocity()
			bullet:SetPhysicsVelocity(Vector(0,0,0))
			changeBulletLife(bullet,bullet.max_pz)
			table.insert(ids,bullet:GetEntityIndex())
		end
	end
	Timers:CreateTimer({
		endTime = 1,
		callback = function() 
			for i,id in ipairs(ids) do
				local entry = EntIndexToHScript(id)
				if IsValidEntity(entry) then
					entry.alive = false
					local dir = entry._lastSp:Normalized()
					entry:SetPhysicsVelocity(- dir * speed_utra)
				end
			end
		end
	})
end

--[[
	极缓领域  靠近的子弹都会被影响速度 -500  脱离领域速度恢复
]]
function TouchSlowArea(data)
	local caster = data.caster
	local target = data.target
	local ability = data.ability
	local speed = data.speed

	if target._extra_damage and not target.hitself then
		local cur_dir = target:GetPhysicsVelocity():Normalized()
		target:AddPhysicsVelocity(cur_dir*speed)
	end
end

function chuidi(data)
	--特效直接在kv中播放
	local caster = data.caster
	--尾巴是打前方还是后方这个需要看动作
	local bullets = FindUnitsInRadius(caster:GetTeamNumber(), caster:GetAbsOrigin(), nil,data.radius or 350,DOTA_UNIT_TARGET_TEAM_BOTH, DOTA_UNIT_TARGET_ALL,DOTA_UNIT_TARGET_FLAG_NONE, FIND_ANY_ORDER, false)
	local ids = {}
	for k,bullet in pairs(bullets) do
		--直接扫飞,飞行方向变反，并且速度达到最高
		local dir = bullet:GetPhysicsVelocity():Normalized()
		bullet:SetPhysicsVelocity(-dir*speed_utra)
	end
end

function saowei(data)
	local caster = data.caster
	--尾巴是打前方还是后方这个需要看动作
	local dir = -caster:GetForwardVector():Normalized()
	local pos = caster:GetAbsOrigin() + dir * 300
	local bullets = FindUnitsInRadius(caster:GetTeamNumber(), pos, nil,data.radius or 150,DOTA_UNIT_TARGET_TEAM_BOTH, DOTA_UNIT_TARGET_ALL,DOTA_UNIT_TARGET_FLAG_NONE, FIND_ANY_ORDER, false)
	local ids = {}
	for k,bullet in pairs(bullets) do
		--直接扫飞,飞行方向变反，并且速度达到最高
		local dir = bullet:GetPhysicsVelocity():Normalized()
		bullet:SetPhysicsVelocity(-dir*speed_utra)
	end
end

function showWarnParticle( data )
	local caster = data.caster
	warnParticle(caster,data.ability)
end

function removeWarnParticle(data)
	local caster = data.caster
	if caster.warn_particle then
		ParticleManager:DestroyParticle(caster.warn_particle,false)
		caster.warn_particle = nil
	end
end

function StartTelet(data)
	local caster = data.activator
	local ability = caster:FindAbilityByName("fangyu3")

	if ability then
		local bf = false
		local cd = ability:GetCooldownTimeRemaining()
		if not ability:IsCooldownReady() then
			bf = true
		end
		ability:EndCooldown()
		ability:OnSpellStart()
		ability:EndCooldown()
		if bf then
			ability:StartCooldown(cd)
		end
	end
end

function StopMusic( data )
	dump(data)
end